﻿using BCCommon;
using BCCommon.Enums;
using BCCommon.Enums.Driver;
using BCCommon.TMS.Driver;
using BCCommon.TMS.Order;
using BCCommon.TMS.Task;
using BCData.Sim.Admin.AdminOperationRecord;
using BCData.Sim.Admin.TreePermission;
using BCData.TMS.Driver;
using BCData.TMS.Order.Order;
using BCDto.Sim.Admin.Admin;
using BCDto.Sim.Admin.AdminOperationRecord;
using BCDto.TMS.KanBan.AgentKanBan;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.KanBan.AgentKanBan
{
    public class AgentKanBanService : IAgentKanBanService
    {
        private readonly IDriverData driverData;
        private readonly IOrderData orderData;
        private readonly IAdminOperationRecordData adminOperationRecordData;
        private readonly ITreePermissionRecordData treePermissionRecordData;

        public AgentKanBanService(IDriverData driverData,
            IOrderData orderData,
            IAdminOperationRecordData adminOperationRecordData,
            ITreePermissionRecordData treePermissionRecordData)
        {
            this.driverData = driverData;
            this.orderData = orderData;
            this.adminOperationRecordData = adminOperationRecordData;
            this.treePermissionRecordData = treePermissionRecordData;
        }

        public PageableList<AdminOperationRecordDto> GetAdminOperationRecords(AdminDto admin, int pageIndex, int pageSize, DateTime? start, DateTime? end)
        {
            int dataCount;

            var list = this.adminOperationRecordData.GetAdminOperationRecords(pageIndex, pageSize, out dataCount, null, null, start, end, admin.CompanyId);

            return new PageableList<AdminOperationRecordDto>
            {
                Count = dataCount,
                Items = list.As<IEnumerable<AdminOperationRecordDto>>()
            };
        }

        public DriverAnalysisDto GetDriverAnalysis(AdminDto admin, DriverRoleType driverRoleType)
        {
            if (admin.AgentRecord == null)
            {
                return new DriverAnalysisDto();
            }
            var driverList = this.driverData.GetListByAgentUuidAndDriverRoleType(admin.AgentRecord.AgentRecordUuid, driverRoleType).Result;
            var todayNew = driverList.Where(p => p.CreateTime.Date == DateTime.Today).Count();
            var yesterdayNum = driverList.Where(p => p.CreateTime.Date == DateTime.Today.AddDays(-1).Date).Count();
            return new DriverAnalysisDto()
            {
                DriverTotalNumber = driverList.Count(),
                TodayNew = todayNew,
                ComparedWithYesterday = yesterdayNum == 0 ? todayNew == 0 ? 0 : 100 : Math.Round(Convert.ToDouble((todayNew - yesterdayNum) / yesterdayNum * 100), 2)
            };
        }

        public DriverDynamicDto GetDriverDynamic(AdminDto admin)
        {
            if (admin.AgentRecord == null)
            {
                return new DriverDynamicDto();
            }
            var driverDynamicInfos = this.driverData.GetDriverDynamicInfo(admin.AgentRecord.AgentRecordUuid).Result;
            var driverDynamicDetails = this.driverData.GetDriverDynamicDetail(admin.AgentRecord.AgentRecordUuid).Result;
            return new DriverDynamicDto()
            {
                DriverDynamicInfos = driverDynamicInfos.As<List<DriverDynamicInfoDto>>(),
                DriverDynamicDetails = driverDynamicDetails.As<List<DriverDynamicDetailDto>>()
            };
        }

        public OrderAnalysisDto GetOrderAnalysis(AdminDto admin, OrderStatus orderStatus)
        {
            if (admin.AgentRecord == null)
            {
                return new OrderAnalysisDto();
            }
            var orderCompleteCount = this.orderData.GetListByAgentRecordId(admin.AgentRecord.AgentRecordId, orderStatus, null).Result;
            var todayNew = this.orderData.GetListByAgentRecordId(admin.AgentRecord.AgentRecordId, orderStatus, DateTime.Today).Result;
            var yesterdayNum = this.orderData.GetListByAgentRecordId(admin.AgentRecord.AgentRecordId, orderStatus, DateTime.Today.AddDays(-1)).Result;
            return new OrderAnalysisDto()
            {
                OrderTotalNumber = orderCompleteCount,
                TodayNew = todayNew,
                ComparedWithYesterday = yesterdayNum == 0 ? todayNew == 0 ? 0 : 100 : Math.Round(Convert.ToDouble((todayNew - yesterdayNum) / yesterdayNum * 100), 2)
            };
        }

        public OrderAreaAnalysisDto GetOrderAreaAnalysis(AdminDto admin, OrderStatus orderStatus, DateTime? completeTime)
        {
            if (admin.AgentRecord == null)
            {
                return new OrderAreaAnalysisDto();
            }
            var orderAreaAnalysisDetailList = this.orderData.GetOrderAreaAnalysisDetailList(admin.AgentRecord.AgentRecordId, orderStatus, null).Result;
            //var orderTransportBusinessAnalyses = orderAreaAnalysisDetailList.GroupBy(p => p.TransportBusiness).Select(g => new OrderTransportBusinessAnalysisDto()
            //{
            //    TransportBusiness = g.Key,
            //    TransportBusinessStr = orderAreaAnalysisDetailList.FirstOrDefault(k => k.TransportBusiness == g.Key).TransportBusinessStr,
            //    OrderTransportBusinessTotalNumber = orderAreaAnalysisDetailList.Where(k => k.TransportBusiness == g.Key).Sum(k => k.OrderTotalNumber)
            //}).OrderBy(k => k.TransportBusiness);
            //var orderAreaAnalysisInfos = orderAreaAnalysisDetailList.GroupBy(p => p.CountyCode).Select(g => new OrderAreaAnalysisInfoDto()
            //{
            //    CountyCode = g.Key,
            //    CountyName = orderAreaAnalysisDetailList.FirstOrDefault(k => k.CountyCode == g.Key).CountyName,
            //    OrderAreaTotalNumber = orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).Sum(k => k.OrderTotalNumber),
            //    OrderAreaAnalysisDetails = orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).GroupBy(l => l.TransportBusiness).Select(m => new OrderAreaAnalysisDetailDto()
            //    {
            //        TransportBusiness = m.Key,
            //        TransportBusinessStr = orderTransportBusinessAnalyses.FirstOrDefault(v => v.TransportBusiness == m.Key).TransportBusinessStr,
            //        CountyCode = g.Key,
            //        CountyName = orderAreaAnalysisDetailList.FirstOrDefault(v => v.CountyCode == g.Key).CountyName,
            //        OrderTotalNumber = orderAreaAnalysisDetailList.FirstOrDefault(v => v.CountyCode == g.Key && v.TransportBusiness == m.Key).OrderTotalNumber,
            //        Proportion = orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).Sum(k => k.OrderTotalNumber) == 0 ? 0 :
            //        Math.Round(Convert.ToDecimal(orderAreaAnalysisDetailList.FirstOrDefault(v => v.CountyCode == g.Key && v.TransportBusiness == m.Key).OrderTotalNumber) / orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).Sum(k => k.OrderTotalNumber), 2)
            //    }).OrderBy(l => l.TransportBusiness).ToList()
            //}).OrderByDescending(p => p.OrderAreaTotalNumber);
            return new OrderAreaAnalysisDto()
            {
                OrderTransportBusinessAnalyses = orderAreaAnalysisDetailList.GroupBy(p => p.TransportBusiness).Select(g => new OrderTransportBusinessAnalysisDto()
                {
                    TransportBusiness = g.Key,
                    TransportBusinessStr = orderAreaAnalysisDetailList.FirstOrDefault(k => k.TransportBusiness == g.Key).TransportBusinessStr,
                    OrderTransportBusinessTotalNumber = orderAreaAnalysisDetailList.Where(k => k.TransportBusiness == g.Key).Sum(k => k.OrderTotalNumber)
                }).OrderBy(k => k.TransportBusiness),
                OrderAreaAnalysisInfos = orderAreaAnalysisDetailList.GroupBy(p => p.CountyCode).Select(g => new OrderAreaAnalysisInfoDto()
                {
                    CountyCode = g.Key,
                    CountyName = orderAreaAnalysisDetailList.FirstOrDefault(k => k.CountyCode == g.Key).CountyName,
                    OrderAreaTotalNumber = orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).Sum(k => k.OrderTotalNumber),
                    OrderAreaAnalysisDetails = orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).GroupBy(l => l.TransportBusiness).Select(m => new OrderAreaAnalysisDetailDto()
                    {
                        TransportBusiness = m.Key,
                        TransportBusinessStr = orderAreaAnalysisDetailList.FirstOrDefault(v => v.TransportBusiness == m.Key).TransportBusinessStr,
                        CountyCode = g.Key,
                        CountyName = orderAreaAnalysisDetailList.FirstOrDefault(v => v.CountyCode == g.Key).CountyName,
                        OrderTotalNumber = orderAreaAnalysisDetailList.FirstOrDefault(v => v.CountyCode == g.Key && v.TransportBusiness == m.Key).OrderTotalNumber,
                        Proportion = orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).Sum(k => k.OrderTotalNumber) == 0 ? 0 :
                        Math.Round(Convert.ToDecimal(orderAreaAnalysisDetailList.FirstOrDefault(v => v.CountyCode == g.Key && v.TransportBusiness == m.Key).OrderTotalNumber) / orderAreaAnalysisDetailList.Where(k => k.CountyCode == g.Key).Sum(k => k.OrderTotalNumber) * 100, 2)
                    }).OrderBy(l => l.TransportBusiness).ToList()
                }).OrderByDescending(p => p.OrderAreaTotalNumber)
            };
        }

        public OrderStatisticDto GetOrderStatistic(AdminDto admin, OrderStatus orderStatus, DateTime? completeTime)
        {
            if (admin.AgentRecord == null)
            {
                return new OrderStatisticDto();
            }
            var orderStatisticInfo = this.orderData.GetOrderStatisticInfo(admin.AgentRecord.AgentRecordId, orderStatus, null).Result;
            return new OrderStatisticDto()
            {
                OrderStatisticInto = orderStatisticInfo.As<List<OrderStatisticInfoDto>>(),
                OrderSumNumber = orderStatisticInfo.Sum(p => p.OrderTotalNumber),
                OrderSumAmount = orderStatisticInfo.Sum(p => p.OrderTotalAmount)
            };
        }

        public PendingTasksDto GetPendingTasks(AdminDto admin, TaskTypeEnum taskType)
        {
            PendingTasksDto pendingTasks = new PendingTasksDto()
            {
                TaskType = taskType
            };
            long? adminId = null;
            if (!admin.IsSystemAccount) adminId = admin.AdminId;
            //获取员工权限列表
            var treePermissionRecordList = this.treePermissionRecordData.GetPermissionRecordListByAdminId(adminId).Result;

            if (taskType == TaskTypeEnum.DriverRealNameVerifies)
            {
                if (treePermissionRecordList.Any(p => p.PermissionCode == "app_drivermenagements_driverinfors_buttonexam"))
                {
                    //司机实名认证审核
                    var driverRealNameVerifiesCount = this.driverData.GetRealNameVerifiesCount(admin.AgentRecord?.AgentRecordUuid, DriverRoleType.Driver, RealNameVerifiesStatus.Pending).Result;
                    pendingTasks.TotalCount = driverRealNameVerifiesCount;
                }
            }
            else if (taskType == TaskTypeEnum.HorsemanRealNameVerifies)
            {
                if (treePermissionRecordList.Any(p => p.PermissionCode == "app_drivermenagements_horsemaninfors_buttonexam"))
                {
                    //司机实名认证审核
                    var horsemanRealNameVerifiesCount = this.driverData.GetRealNameVerifiesCount(admin.AgentRecord?.AgentRecordUuid, DriverRoleType.Horseman, RealNameVerifiesStatus.Pending).Result;
                    pendingTasks.TotalCount = horsemanRealNameVerifiesCount;
                }
            }
            else if (taskType == TaskTypeEnum.DriverVehicleAudit)
            {
                if (treePermissionRecordList.Any(p => p.PermissionCode == "app_drivermenagements_driverinfors_buttonexam"))
                {
                    //司机车辆审核
                    var vehiclePendingAuditCount = this.driverData.GetVehiclePendingAuditCount(admin.AgentRecord?.AgentRecordUuid, DriverRoleType.Driver, DriverStatus.Success).Result;
                    pendingTasks.TotalCount = vehiclePendingAuditCount;
                }
            }
            else if (taskType == TaskTypeEnum.HorsemanVehicleAudit)
            {
                if (treePermissionRecordList.Any(p => p.PermissionCode == "app_drivermenagements_horsemaninfors_buttonexam"))
                {
                    //骑手车辆审核
                    var vehiclePendingAuditCount = this.driverData.GetVehiclePendingAuditCount(admin.AgentRecord?.AgentRecordUuid, DriverRoleType.Horseman, DriverStatus.Success).Result;
                    pendingTasks.TotalCount = vehiclePendingAuditCount;
                }
            }
            else if (taskType == TaskTypeEnum.OrderAssign)
            {
                
            }
            return pendingTasks;
        }
    }
}
